﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace 键盘监控器
{
   public partial class MainWindow : Window
    {
        private readonly static KeyQueue<string> _keyQueue = new KeyQueue<string>();

        #region API
        // Windows API 常量和方法
        private const int WH_KEYBOARD_LL = 13; // 全局键盘钩子
        private const int WM_KEYDOWN = 0x0100;
        private const int WM_SYSKEYDOWN = 0x0104;

        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll")]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        // Win32 API 获取按键名称的声明
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int GetKeyNameText(uint lParam, StringBuilder lpString, int nSize);

        [DllImport("user32.dll")]
        public static extern short GetKeyState(int keyCode);
        #endregion

        #region 定义
        // 定义回调方法的委托
        private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);

        private static HookProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;
        #endregion

        /// <summary>
        /// 窗体构造方法
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();

            this.Loaded += MainWindow_Loaded;
            this.Closing += MainWindow_Closing;
        }

        /// <summary>
        /// 关闭应用程序时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            UnhookWindowsHookEx(_hookID); // 释放钩子
        }

        /// <summary>
        /// 命令：关闭窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// 加载窗口必要的配置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            // 获取屏幕的工作区大小（不包含任务栏）
            var workingArea = SystemParameters.WorkArea;

            // 设置窗口的 Left 和 Top，使其在右下角
            this.Left = workingArea.Right - this.Width - 10;
            this.Top = workingArea.Bottom - this.Height - 10;

            _hookID = SetHook(_proc);

            _keyQueue.QueueChanged += KeyQueue_QueueChanged;
        }

        /// <summary>
        /// 消息队列
        /// </summary>
        /// <param name="item"></param>
        /// <param name="cont"></param>
        /// <exception cref="NotImplementedException"></exception>
        private async void KeyQueue_QueueChanged(Queue<string> item, int cont)
        {
            await Dispatcher.InvokeAsync(() =>
            {
                if (cont >= 10)
                {
                    _keyQueue.Dequeue();
                }

                this.keyText.Text = null;
                foreach (var str in item)
                {
                    this.keyText.Text += str + " ";  // 拼接元素到字符串中
                }

            });
        }

        /// <summary>
        /// 设置钩子
        /// </summary>
        /// <param name="proc"></param>
        /// <returns></returns>
        private static IntPtr SetHook(HookProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        /// <summary>
        /// 钩子回调方法
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN))
            {
                int vkCode = Marshal.ReadInt32(lParam); // 获取虚拟键码
                var key = (System.Windows.Input.Key)KeyInterop.KeyFromVirtualKey(vkCode); // 转换为WPF Key枚举

                // Debug.WriteLine($"Key Pressed: {key}");

                // 检查修饰键的状态
                var modifierKeys = GetModifierKeys();

                var keyCombination = Tuple.Create(key, modifierKeys);

                if (KeyCombinations.ContainsKey(keyCombination))
                {
                    Debug.WriteLine($"Pressed: {KeyCombinations[keyCombination]}");
                    _keyQueue.Enqueue(KeyCombinations[keyCombination]);
                }
                else
                {
                    Debug.WriteLine($"Key Pressed: {key}");
                    _keyQueue.Enqueue(key.ToString());
                }

            }

            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        private static ModifierKeys GetModifierKeys()
        {
            ModifierKeys modifierKeys = ModifierKeys.None;

            if ((GetKeyState(0x10) & 0x8000) != 0) // Shift键
                modifierKeys |= ModifierKeys.Shift;

            if ((GetKeyState(0x11) & 0x8000) != 0) // Ctrl键
                modifierKeys |= ModifierKeys.Control;

            if ((GetKeyState(0x12) & 0x8000) != 0) // Alt键
                modifierKeys |= ModifierKeys.Alt;

            return modifierKeys;
        }

        private static readonly Dictionary<Tuple<System.Windows.Input.Key, ModifierKeys>, string> KeyCombinations = new Dictionary<Tuple<Key, ModifierKeys>, string>()
        {
            // Shift + 数字键
            { Tuple.Create(Key.D1, ModifierKeys.Shift), "!" },
            { Tuple.Create(Key.D2, ModifierKeys.Shift), "@" },
            { Tuple.Create(Key.D3, ModifierKeys.Shift), "#" },
            { Tuple.Create(Key.D4, ModifierKeys.Shift), "$" },
            { Tuple.Create(Key.D5, ModifierKeys.Shift), "%" },
            { Tuple.Create(Key.D6, ModifierKeys.Shift), "^" },
            { Tuple.Create(Key.D7, ModifierKeys.Shift), "&" },
            { Tuple.Create(Key.D8, ModifierKeys.Shift), "*" },
            { Tuple.Create(Key.D9, ModifierKeys.Shift), "(" },
            { Tuple.Create(Key.D0, ModifierKeys.Shift), ")" },
            { Tuple.Create(Key.OemMinus, ModifierKeys.Shift), "_" },
            { Tuple.Create(Key.OemPlus, ModifierKeys.Shift), "+" },

            // Shift + 字母键
            { Tuple.Create(Key.Q, ModifierKeys.Shift), "Q" },
            { Tuple.Create(Key.W, ModifierKeys.Shift), "W" },
            { Tuple.Create(Key.E, ModifierKeys.Shift), "E" },
            { Tuple.Create(Key.R, ModifierKeys.Shift), "R" },
            { Tuple.Create(Key.T, ModifierKeys.Shift), "T" },
            { Tuple.Create(Key.Y, ModifierKeys.Shift), "Y" },
            { Tuple.Create(Key.U, ModifierKeys.Shift), "U" },
            { Tuple.Create(Key.I, ModifierKeys.Shift), "I" },
            { Tuple.Create(Key.O, ModifierKeys.Shift), "O" },
            { Tuple.Create(Key.P, ModifierKeys.Shift), "P" },
            { Tuple.Create(Key.A, ModifierKeys.Shift), "A" },
            { Tuple.Create(Key.S, ModifierKeys.Shift), "S" },
            { Tuple.Create(Key.D, ModifierKeys.Shift), "D" },
            { Tuple.Create(Key.F, ModifierKeys.Shift), "F" },
            { Tuple.Create(Key.G, ModifierKeys.Shift), "G" },
            { Tuple.Create(Key.H, ModifierKeys.Shift), "H" },
            { Tuple.Create(Key.J, ModifierKeys.Shift), "J" },
            { Tuple.Create(Key.K, ModifierKeys.Shift), "K" },
            { Tuple.Create(Key.L, ModifierKeys.Shift), "L" },
            { Tuple.Create(Key.Z, ModifierKeys.Shift), "Z" },
            { Tuple.Create(Key.X, ModifierKeys.Shift), "X" },
            { Tuple.Create(Key.C, ModifierKeys.Shift), "C" },
            { Tuple.Create(Key.V, ModifierKeys.Shift), "V" },
            { Tuple.Create(Key.B, ModifierKeys.Shift), "B" },
            { Tuple.Create(Key.N, ModifierKeys.Shift), "N" },
            { Tuple.Create(Key.M, ModifierKeys.Shift), "M" },

            { Tuple.Create(Key.Q, ModifierKeys.None), "q" },
            { Tuple.Create(Key.W, ModifierKeys.None), "w" },
            { Tuple.Create(Key.E, ModifierKeys.None), "e" },
            { Tuple.Create(Key.R, ModifierKeys.None), "r" },
            { Tuple.Create(Key.T, ModifierKeys.None), "t" },
            { Tuple.Create(Key.Y, ModifierKeys.None), "y" },
            { Tuple.Create(Key.U, ModifierKeys.None), "u" },
            { Tuple.Create(Key.I, ModifierKeys.None), "i" },
            { Tuple.Create(Key.O, ModifierKeys.None), "o" },
            { Tuple.Create(Key.P, ModifierKeys.None), "p" },
            { Tuple.Create(Key.A, ModifierKeys.None), "a" },
            { Tuple.Create(Key.S, ModifierKeys.None), "s" },
            { Tuple.Create(Key.D, ModifierKeys.None), "d" },
            { Tuple.Create(Key.F, ModifierKeys.None), "f" },
            { Tuple.Create(Key.G, ModifierKeys.None), "g" },
            { Tuple.Create(Key.H, ModifierKeys.None), "h" },
            { Tuple.Create(Key.J, ModifierKeys.None), "j" },
            { Tuple.Create(Key.K, ModifierKeys.None), "k" },
            { Tuple.Create(Key.L, ModifierKeys.None), "l" },
            { Tuple.Create(Key.Z, ModifierKeys.None), "z" },
            { Tuple.Create(Key.X, ModifierKeys.None), "x" },
            { Tuple.Create(Key.C, ModifierKeys.None), "c" },
            { Tuple.Create(Key.V, ModifierKeys.None), "v" },
            { Tuple.Create(Key.B, ModifierKeys.None), "b" },
            { Tuple.Create(Key.N, ModifierKeys.None), "n" },
            { Tuple.Create(Key.M, ModifierKeys.None), "m" },

            // 数字键（无Shift）
            { Tuple.Create(Key.D1, ModifierKeys.None), "1" },
            { Tuple.Create(Key.D2, ModifierKeys.None), "2" },
            { Tuple.Create(Key.D3, ModifierKeys.None), "3" },
            { Tuple.Create(Key.D4, ModifierKeys.None), "4" },
            { Tuple.Create(Key.D5, ModifierKeys.None), "5" },
            { Tuple.Create(Key.D6, ModifierKeys.None), "6" },
            { Tuple.Create(Key.D7, ModifierKeys.None), "7" },
            { Tuple.Create(Key.D8, ModifierKeys.None), "8" },
            { Tuple.Create(Key.D9, ModifierKeys.None), "9" },
            { Tuple.Create(Key.D0, ModifierKeys.None), "0" },

            // Ctrl + 常见操作键
            //{ Tuple.Create(Key.C, ModifierKeys.Control), "Ctrl + C (Copy)" },
            //{ Tuple.Create(Key.V, ModifierKeys.Control), "Ctrl + V (Paste)" },
            //{ Tuple.Create(Key.X, ModifierKeys.Control), "Ctrl + X (Cut)" },
            //{ Tuple.Create(Key.Z, ModifierKeys.Control), "Ctrl + Z (Undo)" },
            //{ Tuple.Create(Key.Y, ModifierKeys.Control), "Ctrl + Y (Redo)" },

            // Ctrl + 字母键
            //{ Tuple.Create(Key.A, ModifierKeys.Control), "Ctrl + A (Select All)" },
            //{ Tuple.Create(Key.F, ModifierKeys.Control), "Ctrl + F (Find)" },
            //{ Tuple.Create(Key.S, ModifierKeys.Control), "Ctrl + S (Save)" },

            // Alt + 常见操作键
            //{ Tuple.Create(Key.F4, ModifierKeys.Alt), "Alt + F4 (Close)" },
            //{ Tuple.Create(Key.Tab, ModifierKeys.Alt), "Alt + Tab (Switch App)" },
            //{ Tuple.Create(Key.Escape, ModifierKeys.Alt), "Alt + Escape (Minimize)" },

            // Alt + 字母键
            //{ Tuple.Create(Key.F, ModifierKeys.Alt), "Alt + F (File)" },
            //{ Tuple.Create(Key.E, ModifierKeys.Alt), "Alt + E (Edit)" },

            // 功能键
            { Tuple.Create(Key.F1, ModifierKeys.None), "F1" },
            { Tuple.Create(Key.F2, ModifierKeys.None), "F2" },
            { Tuple.Create(Key.F3, ModifierKeys.None), "F3" },
            { Tuple.Create(Key.F5, ModifierKeys.None), "F5" },
            { Tuple.Create(Key.F6, ModifierKeys.None), "F6" },
            { Tuple.Create(Key.F7, ModifierKeys.None), "F7" },
            { Tuple.Create(Key.F8, ModifierKeys.None), "F8" },
            { Tuple.Create(Key.F9, ModifierKeys.None), "F9" },
            { Tuple.Create(Key.F10, ModifierKeys.None), "F10" },
            { Tuple.Create(Key.F11, ModifierKeys.None), "F11" },
            { Tuple.Create(Key.F12, ModifierKeys.None), "F12" },

            // 特殊字符键
            { Tuple.Create(Key.OemTilde, ModifierKeys.None), "`" },
            { Tuple.Create(Key.OemMinus, ModifierKeys.None), "-" },
            { Tuple.Create(Key.OemPlus, ModifierKeys.None), "=" },
            { Tuple.Create(Key.OemQuestion, ModifierKeys.Shift), "/" },
            { Tuple.Create(Key.OemPeriod, ModifierKeys.None), "." },
            { Tuple.Create(Key.OemComma, ModifierKeys.None), "," },
            { Tuple.Create(Key.OemOpenBrackets, ModifierKeys.None), "[" },
            { Tuple.Create(Key.OemCloseBrackets, ModifierKeys.None), "]" },
            { Tuple.Create(Key.OemBackslash, ModifierKeys.None), "\\" },

            // 新增特殊字符键：如 ~、{ }、[ ]、| 等
            { Tuple.Create(Key.OemTilde, ModifierKeys.Shift), "~" },
            { Tuple.Create(Key.OemOpenBrackets, ModifierKeys.Shift), "{" },
            { Tuple.Create(Key.OemCloseBrackets, ModifierKeys.Shift), "}" }, 
            { Tuple.Create(Key.OemComma, ModifierKeys.Shift), "<" },
            { Tuple.Create(Key.OemPeriod, ModifierKeys.Shift), ">" },
            { Tuple.Create(Key.OemPipe, ModifierKeys.Shift), "|" },

             // 退格键
            { Tuple.Create(Key.Back, ModifierKeys.None), "←" },

            // Home、End、PageUp、PageDown
            { Tuple.Create(Key.Home, ModifierKeys.None), "↖" },
            { Tuple.Create(Key.End, ModifierKeys.None), "↘" },
            { Tuple.Create(Key.PageUp, ModifierKeys.None), "⇞" },
            { Tuple.Create(Key.PageDown, ModifierKeys.None), "⇟" },

            // Delete、Insert
            { Tuple.Create(Key.Delete, ModifierKeys.None), "⌫" },
            { Tuple.Create(Key.Insert, ModifierKeys.None), "⎀" },

            // Esc、CapsLock
            { Tuple.Create(Key.Escape, ModifierKeys.None), "Esc" },
            { Tuple.Create(Key.CapsLock, ModifierKeys.None), "⇪" },

            // Shift、Ctrl、Alt键
            { Tuple.Create(Key.LeftShift, ModifierKeys.None), "↑" },
            { Tuple.Create(Key.RightShift, ModifierKeys.None), "↑" },
            { Tuple.Create(Key.LeftCtrl, ModifierKeys.None), "^" },
            { Tuple.Create(Key.RightCtrl, ModifierKeys.None), "^" },
            { Tuple.Create(Key.LeftAlt, ModifierKeys.None), "⎇" },
            { Tuple.Create(Key.RightAlt, ModifierKeys.None), "⎇" },

            // Win键（可以使用Windows图标，这里表示为"Windows"）
            { Tuple.Create(Key.LWin, ModifierKeys.None), "⌘" },
            { Tuple.Create(Key.RWin, ModifierKeys.None), "⌘" },

            // 方向键（上、下、左、右）用箭头表示
            { Tuple.Create(Key.Up, ModifierKeys.None), "\u2191" },  // 上箭头
            { Tuple.Create(Key.Down, ModifierKeys.None), "\u2193" },  // 下箭头
            { Tuple.Create(Key.Left, ModifierKeys.None), "\u2190" },  // 左箭头
            { Tuple.Create(Key.Right, ModifierKeys.None), "\u2192" },  // 右箭头

            // 空格
            { Tuple.Create(Key.Space, ModifierKeys.None), "╭─╮" },

            // 回车键
            { Tuple.Create(Key.Enter, ModifierKeys.None), "\u21B5" },  // 回车符号
        };

    }
}
